﻿using System;
using System.Data.SqlClient;
using System.Linq;

using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.DataAccess.SqlDatabase;

using Fuse8.ContentManagementFramework.Domain.Special;
using Fuse8.ContentManagementFramework.Domain;

namespace Fuse8.ContentManagementFramework.DataAccess.SqlAccess
{
    internal class CmsEntityMetaInformationDataMapper : BaseSqlEntityDataMapper<CmsEntityMetaInformation, int>
    {
        public CmsEntityMetaInformationDataMapper()
            : base()
        { }

        public override CmsEntityMetaInformation MapFromMulti(string sp, SqlDataReader reader, CmsEntityMetaInformation stepEntity, int index)
        {
            Guard.ArgumentNotEmpty(sp, "sp");
            Guard.ArgumentNotNull(reader, "reader");

            if (stepEntity == null)
            {
                stepEntity = new CmsEntityMetaInformation();
            }

            if (index == 0)
            {
                CmsEntityMetaField stepMetaField = new CmsEntityMetaField
                {
                    Id = reader.GetInt32(reader.GetOrdinal("EntityMetaFieldId")),
                    MetaFieldName = reader.GetString(reader.GetOrdinal("MetaFieldName")),
                    MetaFieldDescription = !reader.IsDBNull(reader.GetOrdinal("MetaFieldDescription")) ?
                        reader.GetString(reader.GetOrdinal("MetaFieldDescription")) :
                        null,
                    MetaFieldType = reader.GetString(reader.GetOrdinal("MetaFieldType")),
                    IsSystem = reader.GetBoolean(reader.GetOrdinal("IsSystem"))
                };

                if (stepEntity.MetaFields == null)
                {
                    stepEntity.MetaFields = new CmsEntityMetaField[] { stepMetaField };
                }
                else
                {
                    stepEntity.MetaFields = stepEntity.MetaFields.Concat(new CmsEntityMetaField[] { stepMetaField }).ToList();
                }
            }
            else if (index == 1)
            {
                int metaFieldId = reader.GetInt32(reader.GetOrdinal("EntityMetaFieldId"));
                CmsEntityMetaFieldLink stepMetaFieldLink = new CmsEntityMetaFieldLink
                {
                    Id = reader.GetInt32(reader.GetOrdinal("EntityMetaFieldLinkId")),
                    EntityMetaFieldId = metaFieldId,
                    EntityTypeParameter = reader.GetString(reader.GetOrdinal("EntityTypeParameter")),
                    DisplayLabel = !reader.IsDBNull(reader.GetOrdinal("DisplayLabel")) ?
                        reader.GetString(reader.GetOrdinal("DisplayLabel")) :
                        null,
                    IsAllowMultipleValues = reader.GetBoolean(reader.GetOrdinal("IsAllowMultipleValues")),
                    MetaFieldValues = !reader.IsDBNull(reader.GetOrdinal("MetaFieldValues")) ?
                        reader.GetString(reader.GetOrdinal("MetaFieldValues")) :
                        null,
                    DefaultValue = !reader.IsDBNull(reader.GetOrdinal("DefaultValue")) ?
                        reader.GetString(reader.GetOrdinal("DefaultValue")) :
                        null,
                    EditorName = !reader.IsDBNull(reader.GetOrdinal("EditorName")) ?
                        reader.GetString(reader.GetOrdinal("EditorName")) :
                        null,
                    IsRequired = reader.GetBoolean(reader.GetOrdinal("IsRequired")),
                    MetaFieldOrder = reader.GetInt32(reader.GetOrdinal("MetaFieldOrder")),
                    EntityMetaField = stepEntity.MetaFields.FirstOrDefault(p => p.Id == metaFieldId)
                };

                if (stepEntity.MetaFieldLinks == null)
                {
                    stepEntity.MetaFieldLinks = new CmsEntityMetaFieldLink[] { stepMetaFieldLink };
                }
                else
                {
                    stepEntity.MetaFieldLinks = stepEntity.MetaFieldLinks.Concat(new CmsEntityMetaFieldLink[] { stepMetaFieldLink }).ToList();
                }
            }
            else if (index == 2)
            {
                int metaFieldLinkId = reader.GetInt32(reader.GetOrdinal("EntityMetaFieldLinkId"));
                CmsEntityMeta stepMeta = new CmsEntityMeta
                {
                    Id = reader.GetInt32(reader.GetOrdinal("EntityMetaId")),
                    EntityMetaFieldLinkId = metaFieldLinkId,
                    EntityId = reader.GetInt32(reader.GetOrdinal("EntityId")),
                    EntityMetaValue = reader.GetString(reader.GetOrdinal("EntityMetaValue")),
                    EntityMetaFieldLink = stepEntity.MetaFieldLinks.FirstOrDefault(p => p.Id == metaFieldLinkId)
                };

                if (stepEntity.Metas == null)
                {
                    stepEntity.Metas = new CmsEntityMeta[] { stepMeta };
                }
                else
                {
                    stepEntity.Metas = stepEntity.Metas.Concat(new CmsEntityMeta[] { stepMeta }).ToList();
                }
            }
            else
            {
                throw new InvalidOperationException(string.Format("Stored procedure {0} can't return more than {1} result", sp, index));
            }

            return stepEntity;
        }
    }
}
